package korkd.tower;

import java.util.Random;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.ZoomCamera;
import org.anddev.andengine.engine.camera.hud.HUD;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.handler.timer.ITimerCallback;
import org.anddev.andengine.engine.handler.timer.TimerHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException;
import org.anddev.andengine.util.Debug;
import org.anddev.andengine.util.path.Path;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.text.ChangeableText;
import org.anddev.andengine.entity.text.Text;
import org.anddev.andengine.entity.util.FPSCounter;
import org.anddev.andengine.extension.texturepacker.opengl.texture.util.texturepacker.TexturePack;
import org.anddev.andengine.extension.texturepacker.opengl.texture.util.texturepacker.TexturePackLoader;
import org.anddev.andengine.extension.texturepacker.opengl.texture.util.texturepacker.TexturePackTextureRegionLibrary;
import org.anddev.andengine.extension.texturepacker.opengl.texture.util.texturepacker.exception.TexturePackParseException;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.font.Font;
import org.anddev.andengine.opengl.font.FontFactory;
import org.anddev.andengine.opengl.texture.ITexture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.path.ITiledMap;
import org.anddev.andengine.util.path.astar.AStarPathFinder;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Typeface;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.Toast;

public class Game extends BaseGameActivity {
	// ===========================================================
	// Constants
	// ===========================================================
	

	// ===========================================================
	// Fields
	// ===========================================================

	private Scene mMainScene;
	private Map mWorldMap;
	private ZoomCamera mZoomCamera;
	private BitmapTextureAtlas mFontTexture;
	private Font mFont;
	private float mZoom = 1.0f;
	private HUD mHUD;
	private Player mPlayer;
	private Kingdom mKingdom;
	private TMXTiledMap mTMXTemplate;
	
	private ITexture mSpritesheetTexture;
	
	public static TexturePackTextureRegionLibrary TexturePack;
	public static DisplayMetrics Metrics;
	public static Context GameContext;
	
	// ===========================================================
	// Constructors
	// ===========================================================

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	@Override
	public Engine onLoadEngine() {
		
		// Determine the resolution of the screen
		Game.Metrics = new DisplayMetrics();
		this.getWindowManager().getDefaultDisplay().getMetrics(Metrics);
		
		// Set the global context
		Game.GameContext = this;
		
		// Set the camera to that resolution
		this.mZoomCamera = new ZoomCamera(0,0,Metrics.widthPixels,Metrics.heightPixels);

		//Log.i("RES:", Integer.toString(metrics.widthPixels) + " " + Integer.toString(metrics.heightPixels));
		
		// Generate the engine with the given resolution and camera.
		return new Engine(new EngineOptions(true, ScreenOrientation.PORTRAIT, new RatioResolutionPolicy(Metrics.widthPixels,Metrics.heightPixels), this.mZoomCamera));
	}

	@Override
	public void onLoadResources() {
		// Load all the TMX files
		try {
			final TMXLoader tmxLoader = new TMXLoader(this, this.mEngine.getTextureManager(), TextureOptions.REPEATING_BILINEAR);
			this.mTMXTemplate = tmxLoader.loadFromAsset(this, "tmx/Map.tmx");
		} catch (final TMXLoadException tmxle) {
			Toast.makeText(this, "Error loading TMX file!", Toast.LENGTH_LONG).show();
			Debug.e(tmxle);
		}
		
		FontFactory.setAssetBasePath("fonts/");
		
		// Font texture
		this.mFontTexture = new BitmapTextureAtlas(128,128,TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mFont = FontFactory.createFromAsset(this.mFontTexture, this, "Arkham_reg.TTF", 24, true, Color.YELLOW);
		this.mEngine.getTextureManager().loadTexture(this.mFontTexture);
		this.mEngine.getFontManager().loadFont(this.mFont);
		
		// Load the texture sheet
		try 
		{
            BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
            final TexturePack spritesheetTexturePack = new TexturePackLoader(this, "gfx/sheet/").loadFromAsset(this, "TextureSheet.xml");
            this.mSpritesheetTexture = spritesheetTexturePack.getTexture();
            Game.TexturePack = spritesheetTexturePack.getTexturePackTextureRegionLibrary();
            this.mEngine.getTextureManager().loadTexture(this.mSpritesheetTexture);
		} 
		catch (final TexturePackParseException e)
		{
            Debug.e(e);
		}
	}

	@Override
	public Scene onLoadScene() {
		// TODO: New Game vs Continue
		
		// Initialize the Scene Manager
	    SceneManager.INSTANCE = new SceneManager(mEngine, mZoomCamera);
	    
		// Setup the Scene and HUD
	    mMainScene = new Scene();
	    mHUD = createHUD();
	    
	    // Register the Scene and HUD
	    SceneManager.INSTANCE.addScene(mMainScene, mHUD);
		
		return mMainScene;
	}

	@Override
	public void onLoadComplete() {
		// Create the WorldMap
		mWorldMap = new Map(mTMXTemplate, mZoomCamera);
		
		// Register the map as a touch listener to the Scene
		mMainScene.setOnSceneTouchListener(mWorldMap);
		SceneManager.INSTANCE.attachToCurrent(mWorldMap.getMap().getTMXLayers().get(0));
		
		// Configure the camera to be bound by the map
		this.mZoomCamera.setBounds(0, mWorldMap.getWidth(), 0, mWorldMap.getHeight());
		this.mZoomCamera.setBoundsEnabled(true);
		
		mKingdom = new Kingdom(mWorldMap);
	
		// Create the Player
		mPlayer = new Player(this);
	}
	
	@Override
	public boolean onKeyDown(final int pKeyCode, final KeyEvent pEvent) {
		if(pKeyCode == KeyEvent.KEYCODE_MENU && pEvent.getAction() == KeyEvent.ACTION_DOWN) {
			return true;
		} else {
			return super.onKeyDown(pKeyCode, pEvent);
		}
	}

	// ===========================================================
	// Methods
	// ===========================================================
	
	public HUD createHUD()
	{
		final HUD hud = new HUD();
		
		// Register the FPS counter
		final FPSCounter fpsCounter = new FPSCounter();
		this.mEngine.registerUpdateHandler(fpsCounter);
		
		final ChangeableText FPSText = new ChangeableText(0,0, this.mFont, "FPS: ", 7);
		
		// Set the update handler to display the FPS
		mMainScene.registerUpdateHandler(new TimerHandler(1.0f, true, new ITimerCallback() {
			
			@Override
			public void onTimePassed(TimerHandler pTimerHandler) {
				FPSText.setText("FPS: " + fpsCounter.getFPS());
			}}));
		
		// Define the ZoomOut button as a rectangle
		Rectangle ZoomOut = new Rectangle(mZoomCamera.getWidth()-60, mZoomCamera.getHeight()-60, 50, 50)
		{
			@Override
			public boolean onAreaTouched(final TouchEvent pTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY)
			{				
				if(pTouchEvent.getAction() == MotionEvent.ACTION_DOWN)
				{
					if((mZoom * 0.5f) > 0.2f)
					{
						mZoom *= 0.5f;
					}
					else
					{
						mZoom = 0.2f;
					}
					
					mZoomCamera.setZoomFactor(mZoom);
				}
				return true;
			}
		};
		
		// Define the ZoomIn button as a rectangle
		Rectangle ZoomIn = new Rectangle(mZoomCamera.getWidth()-120, mZoomCamera.getHeight()-55, 40, 40)
		{
			@Override
			public boolean onAreaTouched(final TouchEvent pTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY)
			{				
				if(pTouchEvent.getAction() == MotionEvent.ACTION_DOWN)
				{
					if((mZoom * 2.0f) <= 1.0f)
					{
						if(mZoom == 0.2f)
						{
							mZoom = 0.25f;
						}
						else
						{
							mZoom *= 2.0f;
						}
					}
					else
					{
						mZoom = 1.0f;
					}
					
					mZoomCamera.setZoomFactor(mZoom);
				}
				return true;
			}
		};

		// Set the colors of the Zoom in and out buttons
		ZoomOut.setColor(0.0f, 1.0f, 0.0f, 0.2f);
		ZoomIn.setColor(0.0f, 1.0f, 1.0f, 0.2f);
		
		// Attach all the elements
		hud.attachChild(FPSText);
		hud.attachChild(ZoomOut);
		hud.registerTouchArea(ZoomOut);
		hud.attachChild(ZoomIn);
		hud.registerTouchArea(ZoomIn);
		
		return hud;
	}
}